#include <array>
#include <iostream>
#include <type_traits>
typedef union {
  int a;
  float b;
} B;

class A {};
enum E {};
struct SA {
  int func() const &;
};
int f();
template <typename> struct PM_traits {};
template <class T, class U> struct PM_traits<U T::*> { using member_type = U; };
int main() {
  using namespace std;
  cout << boolalpha;
  cout << std::is_floating_point<int>::value << "\n";       // false
  cout << std::is_floating_point<float>::value << "\n";     // true
  cout << std::is_array<A>::value << "\n";                  // false
  cout << std::is_array<A[]>::value << "\n";                // true
  cout << std::is_array<std::array<int, 2>>::value << "\n"; // false
  cout << std::is_enum<E>::value << "\n";                   // true
  cout << std::is_enum<int>::value << "\n";                 // false
  cout << std::is_union<B>::value << "\n";                  // true
  cout << std::is_union<A>::value << "\n";                  // false
  cout << std::is_function<SA>::value << "\n";              // false
  cout << std::is_function<int(int)>::value << "\n";        // true
  cout << std::is_function<decltype(f)>::value << "\n";     // true
  cout << std::is_function<decltype(f)>::value << "\n";     // true
  using T = PM_traits<decltype(&SA::func)>::member_type; // T 为 int() const&
  cout << std::is_function<T>::value << "\n";            // true
}
